﻿#include "SearchTable.h"
#include "mainwindow.h"
#include "public.h"
#include "easylogging++.h"

SearchTable::SearchTable(MainWindow& mw, std::shared_ptr<SerialPort> sp) : mainWindow(mw), serialPort(sp) {
	this->startSearchTable = constructMsgData({ 0x05, 0x04, 0x02, 0xe8 }, 0x04, {});
	this->stopSearchTable = constructMsgData({ 0x06, 0x04, 0x02, 0xe8 }, 0x04, {});
	this->queryNodeInfo = constructMsgData({ 0x65, 0x03, 0x03, 0xe8 }, 0x03, {});
}

void SearchTable::sendStartSearchTable() {
	auto msg_data = this->startSearchTable;
	QByteArray msg = vectorToByteArray(msg_data);
	if (!this->serialPort->cacheWaitConfirmMsg(SerialPort::startSearchTableReq, msg)) {
		LOG(ERROR) << "Message has not been confirmed, cmd:" << convertToString(SerialPort::startSearchTableReq).toStdString() << ", msg:" << convertToString(msg).toStdString();
		return;
	}
	this->serialPort->sendMsg(msg);
}

void SearchTable::sendStopSearchTable() {
	auto msg_data = this->stopSearchTable;
	QByteArray msg = vectorToByteArray(msg_data);
	if (!this->serialPort->cacheWaitConfirmMsg(SerialPort::stopSearchTableReq, msg)) {
		LOG(ERROR) << "Message has not been confirmed, cmd:" << convertToString(SerialPort::stopSearchTableReq).toStdString() << ", msg:" << convertToString(msg).toStdString();
		return;
	}
	this->serialPort->sendMsg(msg);
}

void SearchTable::sendQueryNodeInfoAux() {
	auto msg_data = this->queryNodeInfo;
	QByteArray msg = vectorToByteArray(msg_data);
	this->serialPort->sendMsg(msg);
}

void SearchTable::handleStartSearchTableResult(const QByteArray& relayMessage) {
	LOG(INFO) << convertToString(relayMessage).toStdString();
	this->serialPort->confirmWaitConfirmMsg(SerialPort::startSearchTableReq);
}

void SearchTable::handleStopSearchTableResult(const QByteArray& relayMessage) {
	LOG(INFO) << convertToString(relayMessage).toStdString();
	this->serialPort->confirmWaitConfirmMsg(SerialPort::stopSearchTableReq);
}

void SearchTable::handleSlaveNodeReport(const QByteArray& relayMessage) {
	LOG(INFO) << convertToString(relayMessage).toStdString();
	uint16_t cnt = relayMessage[10]; // 本次应答的节点总数量m
	LOG(INFO) << "cnt:" << cnt;
	for (int i = 0; i < cnt; ++i) {
		std::vector<int> nodeAddr;
		nodeAddr.push_back(relayMessage[11 + i * 6 + 5]);
		nodeAddr.push_back(relayMessage[11 + i * 6 + 4]);
		nodeAddr.push_back(relayMessage[11 + i * 6 + 3]);
		nodeAddr.push_back(relayMessage[11 + i * 6 + 2]);
		nodeAddr.push_back(relayMessage[11 + i * 6 + 1]);
		nodeAddr.push_back(relayMessage[11 + i * 6 + 0]);
		auto nodeAddrStr = convertToStringToShow(vectorToByteArray(nodeAddr));
		mainWindow.updateSearchTableViewModel(nodeAddrStr);
	}
}

void SearchTable::sendQueryNodeInfo() {
	std::vector<int> content = { hasSearchedNodeInfoCnt & 0xFF, (hasSearchedNodeInfoCnt >> 16) & 0xFF, 0x10 };
	this->queryNodeInfo = constructMsgData({ 0x65, 0x03, 0x03, 0xe8 }, 0x03, content);
	// 发送查询从节点信息
	sendQueryNodeInfoAux();
}

void SearchTable::handleQueryNodeInfoResult(const QByteArray& relayMessage) {
	uint32_t currentCnt = relayMessage[14];
	hasSearchedNodeInfoCnt += currentCnt;
	for (int index = 0; index < currentCnt; ++index) {
		std::vector<int> nodeAddr;
		nodeAddr.push_back(relayMessage[15 + index * 19 + 5]);
		nodeAddr.push_back(relayMessage[15 + index * 19 + 4]);
		nodeAddr.push_back(relayMessage[15 + index * 19 + 3]);
		nodeAddr.push_back(relayMessage[15 + index * 19 + 2]);
		nodeAddr.push_back(relayMessage[15 + index * 19 + 1]);
		nodeAddr.push_back(relayMessage[15 + index * 19 + 0]);
		auto nodeAddrStr = convertToStringToShow(vectorToByteArray(nodeAddr));
		mainWindow.updateSearchTableViewModel(nodeAddrStr);
	}
	if (currentCnt == 0x10) {
		// 发送查询从节点信息
		sendQueryNodeInfo();
	}
	else {
		// 为下次搜索准备
		hasSearchedNodeInfoCnt = 0;
	}
}